﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using Ling.P2P.Provider;
using Ling.P2P.DemoLib;

namespace Ling.P2P.PClient
{
    public partial class ClientMainWnd : Form
    {
        public ClientMainWnd()
        {
            InitializeComponent();

            Program.P2PClient.ReceiveData += new ReceiveEventHandler(P2PClient_ReceiveData); // 通过此事件处理收到的除文件传送以外的任何数据。
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (!DesignMode)
            {
                Text = string.Format("Ling.P2P客户端示例 - [{0}]", Program.Me);
                lab_Name.Text = Program.Me;
                BindingClients();
            }
        }

        public void BindingClients()
        {
            lock (Program.LogInClients)
            {
                listBox1.Items.Clear();
                foreach (ClientInfo ci in Program.LogInClients)
                    listBox1.Items.Add(ci);
            }
        }

        private void P2PClient_ReceiveData(TcpP2PEntry sender, ReceiveDataEventArgs e)
        {
            // 因为消息是该 P2P 核心库的关键，任何数据在发送前都必须要先发送与其对应种类的消息。
            // 所以理论上消息为空的请况在这里一般不会出现，在这里我一样作了判断，算是有点强迫症吧。
            if (e.Message == null) return;

            byte[] data;
            int len;
            switch (e.Message.Value.MessageType)
            { 
                case P2PConstants.MSG_UPDATE_CLIENTS : // 有新客户端登入时，服务端发来的更新消息。
                    // 先接收后续内容的长度。
                    data = Program.P2PClient.ReceiveKnownData(e.skt, sizeof(int));
                    len = BitConverter.ToInt32(data, 0);
                    data = Program.P2PClient.ReceiveKnownData(e.skt, len); // 接收内容。
                    ClientInfo ci = ClientInfo.Deserialization(data);
                    if (ci != null)
                    {
                        lock (Program.LogInClients)
                        {
                            Program.LogInClients.Add(ci);
                            Invoke(new MethodInvoker(delegate
                            {
                                listBox1.Items.Add(ci);
                            }));
                        }
                    }
                    break;
                case P2PConstants.MSG_SEND_TEXT :   // 从其它客户端发来的文本消息。
                    //
                    break;
                case P2PConstants.MSG_SEND_IMG : // 从其它客户端发来的除文件以外，但又非文件的其它二进制内容（如图片音频等）。
                    //
                    break;
            }
            e.skt.Close();
            e.skt.Dispose();
        }
    }
}
